package org.elec.mac.inter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.elec.mac.entity.*;
import org.elec.mac.exception.ErrorCode;
import org.elec.mac.gizwits.GizApi;
import org.elec.mac.service.*;
import org.elec.mac.utils.PriceUtil;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by wangtao on 2018/6/12.
 */
@Slf4j
@Controller
@RequestMapping(value = "/rev")
public class ReveiveController {

    @Autowired
    private SProductService sProductService;

    @Autowired
    private SOrderService  sOrderService;

    @Autowired
    private SMachineMaterialService sMachineMaterialService;

    @Autowired
    private SOrderDetailService sOrderDetailService;

    @Autowired
    private SFormulaService sFormulaService;

    @Autowired
    private SSaleService sSaleService;

    @Autowired
    private SSaleTotalService sSaleTotalService;

    @Autowired
    private GizApi gizApi;

    @Value("${annex.image.url}")
    private String imageurl;

    @RequestMapping(value = "/accept.do")
    public void receiveHandler(HttpServletRequest request, HttpServletResponse response,
                              @RequestParam(value = "mach", required = false)String machid,
                              @RequestParam(value = "recid", required = false)String recid,
                              @RequestParam(value = "did", required = false)String did ) throws IOException {

        JSONObject result = new JSONObject();
        did = "ANybXnbmVgy6PTKjZwxf82";
        int code = 0;
        result.put("code", code);
        result.put("msg", "成功");

        ExecuteResult result1 = new ExecuteResult();
        result1.setSuccess(true);
        result1.setMsg("成功");

        Map<String, Object> param = new HashMap<>();
        try {

            if (StringUtils.isBlank(recid)) {
                result1.setSuccess(false);
                log.info("领取编号不能为空");
                result.put("code", -1);
                result.put("msg", "领取编号不能为空");
            }

            if(StringUtils.isBlank(machid)) {
                result1.setSuccess(false);
                log.info("机台id不能为空");
                result.put("code", -1);
                result.put("msg", "机台id不能为空");
            }

            if(result1.isSuccess()) {
                param.put("receiveno", recid);
                SOrder order = sOrderService.get(param);
                if (order != null) {
                    if (!order.getReceiveno().equals(order.getId().substring(8))) {
                        log.info("该领取编号无效");
                        result.put("code", -2);
                        result.put("msg", "该领取编号无效");
                        result1.setSuccess(false);
                    }
                    if (order.getReceiveTime() != null) {
                        log.info("该商品已领取");
                        result.put("code", -3);
                        result.put("msg", "该商品已领取");
                        result1.setSuccess(false);
                    }
                    if(result1.isSuccess()) {
                        String oid = order.getId();
                        Long mid = Long.parseLong(machid);
                        param.clear();
                        param.put("oid", oid);
                        List<SOrderDetail> detailList = sOrderDetailService.list(param);
                        for(SOrderDetail sOrderDetail : detailList) {
                            param.clear();
                            param.put("id", sOrderDetail.getPid());
                            SProduct sProduct = sProductService.get(param);

                            SSale sSale = new SSale();
                            sSale.setOid(oid);
                            sSale.setMachid(mid);
                            sSale.setCateid(sProduct.getCid());
                            sSale.setPid(sProduct.getId());
                            sSale.setSale(new Long(sOrderDetail.getCounts()));
                            sSale.setPprice(sProduct.getPprice() * sSale.getSale());
                            sSale.setOprice(sOrderDetail.getPrice() * sSale.getSale());
                            sSale.setSprice(sOrderDetail.getCprice() * sSale.getSale());
                            sSale.setProfit(sSale.getSprice() - sSale.getPprice());
                            sSale.setCreateTime(new Date());
                            sSaleService.insertSaleProduct(sSale);

                            param.clear();
                            param.put("machid", mid);
                            param.put("cateid", sProduct.getCid());
                            param.put("pid", sProduct.getId());
                            param.put("createTime", new Date());
                            SSaleTotal sSaleTotal = sSaleTotalService.get(param);

                            if(sSaleTotal == null) {
                                sSaleTotal = new SSaleTotal();
                                sSaleTotal.setPid(sProduct.getId());
                                sSaleTotal.setMachid(mid);
                                sSaleTotal.setCateid(sProduct.getCid());
                                sSaleTotal.setSale(new Long(sOrderDetail.getCounts()));
                                sSaleTotal.setAmount(sOrderDetail.getCprice() * sSaleTotal.getSale());
                                sSaleTotal.setProfit(sSale.getSprice() - sSale.getPprice());
                                sSaleTotal.setCreateDate(new Date());
                                sSaleTotalService.insertSaleProductTotal(sSaleTotal);
                            } else {
                                sSaleTotal.setPid(sProduct.getId());
                                sSaleTotal.setMachid(mid);
                                sSaleTotal.setCateid(sProduct.getCid());
                                sSaleTotal.setSale(sSaleTotal.getSale() + new Long(sOrderDetail.getCounts()));
                                sSaleTotal.setAmount(sSaleTotal.getAmount() + sOrderDetail.getCprice() * sSaleTotal.getSale());
                                sSaleTotal.setProfit(sSaleTotal.getProfit() + sSale.getSprice() - sSale.getPprice());
                                sSaleTotalService.updateVipOrder(sSaleTotal);
                            }
                        }

                        //机台原料
                        param.clear();
                        param.put("machid", machid);
                        param.put("sign", 1);
                        List<SMachineMaterial> machineMaterialList = sMachineMaterialService.list(param);
                        param.clear();
                        param.put("machid", machid);
                        param.put("sign", 0);
                        List<SMachineMaterial> machineBasicsList = sMachineMaterialService.list(param);

                        //获取订单里面的产品列表
                        param.clear();
                        param.put("oid", oid);
                        List<SOrderDetail> orderDetailList = sOrderDetailService.list(param);
                        for (SOrderDetail item : orderDetailList) {
                            //获取订单里每个产品所需的原料
                            param.clear();
                            param.put("pid", item.getPid());
                            param.put("sign", 1);
                            List<SFormula> productMaterial = sFormulaService.list(param);
                            //获取订单里每个产品所需的配方
                            param.clear();
                            param.put("pid", item.getPid());
                            param.put("sign", 0);
                            List<SFormula> productBasics = sFormulaService.list(param);


                            //判断整个机台中的产品原料是否能够制作订单中包含的所有产品的原料以及配方
                            boolean sign = check(productMaterial,machineMaterialList);
                            boolean flag = check(productBasics,machineBasicsList);
                            log.info("flag : " + flag);
                            log.info("sign : " + sign);

                            if(sign && flag) {
                                //向机台发送数据点
                                try {
                                    //测试发送数据点
                                    log.info("机台标识：" + did);
                                    JSONObject object = new JSONObject();
                                    object.put("s_test", true);
                                    object.put("temperature", 46);
                                    object.put("sugar", 32);
                                    result.put("dataPoint", object);

                                    boolean a = gizApi.writeStandardDataPoint(did,object);
                                    if(a) {
                                        log.info("发送设备数据点：SUCCESS!");
                                        Iterator b = object.keys();
                                        while (b.hasNext()) {
                                            String o = b.next().toString();
                                            log.info("key : " + o + " | value : " + object.get(o));
                                        }
                                    } else {
                                        log.info("发送设备数据点失败：FAIL!");
                                    }
                                } catch (Exception e) {
                                    log.error("发送设备数据点异常：" + e);
                                }
                            }
                        }
                    }
                } else {
                    log.info("该领取编号无效");
                    result.put("code", -2);
                    result.put("msg", "该领取编号无效");
                    result1.setSuccess(false);
                }
            }


        } catch (Exception ex) {
            log.error("领取商品错误", ex);
            code = ErrorCode.ERR_UNKNOWN;
            result.put("code", code);
            result.put("msg", "[" + code + "]领取商品错误");
        }
        response.getWriter().write(result.toString());
    }

    private boolean check(List<SFormula> formulas,List<SMachineMaterial> machineMaterials){
        for (SFormula sFormula : formulas) {
            log.info("sMachineMaterial.getMid : " + sFormula.getMaid());
            List<SMachineMaterial> sMachineMaterials = machineMaterials
                    .stream()
                    .filter(sMachineMaterial -> sMachineMaterial.getMid().equals(sFormula.getMaid()))
                    .collect(Collectors.toList());

            log.info("sFormulas.size : " + sMachineMaterials.size());
            if(sMachineMaterials.size() == 1){
                SMachineMaterial sMachineMaterial = sMachineMaterials.get(0);
                if(sMachineMaterial.getAmount() < sFormula.getAmount()){
                    log.info("sMachineMaterial.getAmount() < sFormula.getAmount()");
                    return false;
                }
                //有
            }else{
                log.info("没有");
                //没有
                return false;
            }
        }

        return true;
    }


    @RequestMapping(value = "/getorder.do")
    private void oneOrderHadler(HttpServletRequest request, HttpServletResponse response,
                                @RequestParam(value = "recid", required = false) String recid) throws Exception {
        JSONObject result = new JSONObject();
        int code = 0;
        result.put("code", code);
        result.put("msg", "成功");

        if(StringUtils.isBlank(recid)) {
            result.put("code", -1);
            result.put("msg", "recid不能为空");
        } else {
            Map<String, Object> param = new HashMap<>();
            param.put("receiveno", recid);
            SOrder sorder = sOrderService.get(param);
            if(sorder != null) {
                try {
                    JSONObject order = new JSONObject();
                    order.put("orderid", sorder.getId());
                    order.put("userinfo", sorder.getUserInfo());
                    order.put("refund", sorder.getRefund());
                    order.put("refstat", sorder.getRefstat());
                    order.put("status", sorder.getStatus());
                    order.put("tprice", PriceUtil.toPriceString(sorder.getTprice()));
                    order.put("acprice", PriceUtil.toPriceString(sorder.getAcprice()));
                    order.put("total", sorder.getTotal());
                    order.put("paymode", sorder.getPaymode());
                    order.put("receivetime", sorder.getReceiveTime());
                    result.put("body", order);
                    param.clear();
                    param.put("oid", sorder.getId());
                    List<Map<String, Object>> orderDetailList = sOrderDetailService.orderDetails(param);
                    JSONArray materials = new JSONArray();
                    for (Map item : orderDetailList) {
                        String[] str = item.get("materials").toString().split(",");
                        for (int i = 0; i < str.length; i++) {
                            materials.put(Integer.parseInt(str[i]));
                        }
                        item.put("materials", materials);
                        item.put("imageurl", imageurl + item.get("imageurl"));
                        item.put("cprice",Double.parseDouble(PriceUtil.toPriceString((long)item.get("cprice"))));
                        item.put("price",Double.parseDouble(PriceUtil.toPriceString((long)item.get("price"))));
                    }
                    order.put("orderDetail", orderDetailList);
                    log.info("order===>：" + order);
                } catch (Exception e) {
                    e.printStackTrace();
                    result.put("code", -2);
                    result.put("msg", "获取订单接口出错");
                }
            } else {
                result.put("code", -2);
                result.put("msg", "该领取编号无效");
            }
        }
        log.info(result.toString());
        response.getWriter().write(result.toString());
    }
}
